package com.ruoyi.lxy.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.lxy.domain.*;
import com.ruoyi.lxy.domain.vo.TDependantVo;
import com.ruoyi.lxy.mapper.*;
import com.ruoyi.lxy.zust.domain.TStaff;
import com.ruoyi.lxy.zust.service.ITStaffService;
import lombok.RequiredArgsConstructor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.stereotype.Service;
import com.ruoyi.lxy.domain.bo.TSelectUserBo;
import com.ruoyi.lxy.domain.vo.TSelectUserVo;
import com.ruoyi.lxy.service.ITSelectUserService;
import com.ruoyi.lxy.domain.TPolicy;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 用户选择Service业务层处理
 *
 * @author ruoyi
 * @date 2023-10-09
 */
@RequiredArgsConstructor
@Service
@MapperScan("com.ruoyi.lxy.mapper")
public class TSelectUserServiceImpl implements ITSelectUserService {

    private final TSelectUserMapper baseMapper;
    private final TTimeMapper timeMapper;
    private final TProjectMapper projectMapper;
    private final TRouteMapper routeMapper;
    private final TPolicyMapper policyMapper;
    private final TDependantMapper dependantMapper;
    private final TDependantServiceImpl tDependantService;
    private final TUserMapper userMapper;
    private final ITStaffService itStaffService;


    /**
     * 查询用户选择
     */
    @Override
    public TSelectUserVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询用户选择列表
     */
    @Override
    public TableDataInfo<TSelectUserVo> queryPageList(TSelectUserBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TSelectUser> lqw = buildQueryWrapper(bo);
        Page<TSelectUserVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询用户选择列表
     */
    @Override
    public List<TSelectUserVo> queryList(TSelectUserBo bo) {
        LambdaQueryWrapper<TSelectUser> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<TSelectUser> buildQueryWrapper(TSelectUserBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TSelectUser> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getYear() != null, TSelectUser::getYear, bo.getYear());
        lqw.eq(bo.getProjectId() != null, TSelectUser::getProjectId, bo.getProjectId());
        lqw.eq(bo.getRound() != null, TSelectUser::getRound, bo.getRound());
        lqw.eq(bo.getTimeId() != null, TSelectUser::getTimeId, bo.getTimeId());
        lqw.eq(bo.getUserId() != null, TSelectUser::getUserId, bo.getUserId());
        lqw.eq(bo.getArea() != null, TSelectUser::getArea, bo.getArea());
        lqw.eq(bo.getSatisfaction() != null, TSelectUser::getSatisfaction, bo.getSatisfaction());
        lqw.eq(StringUtils.isNotBlank(bo.getComment()), TSelectUser::getComment, bo.getComment());
        lqw.eq(bo.getWriteTime() != null, TSelectUser::getWriteTime, bo.getWriteTime());
        return lqw;
    }

    /**
     * 新增用户选择
     */
    @Override
    public Boolean insertByBo(TSelectUserBo bo) {
        TSelectUser add = BeanUtil.toBean(bo, TSelectUser.class);
        validEntityBeforeSave(add);
        TTime tTime = timeMapper.selectById(add.getTimeId());
        TRoute tRoute = routeMapper.selectById(tTime.getRouteId());
        TProject tProject = projectMapper.selectById(tRoute.getProjectId());
        add.setProjectId(tProject.getId());
        add.setArea(tRoute.getAreaCode());
        add.setYear(tProject.getYear());
        add.setWriteTime(new Date());
        add.setRound(0);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
            tTime.setCount(tTime.getCount() + 1);
            tTime.setStaffCount(tTime.getStaffCount() + 1);
            timeMapper.updateById(tTime);

        }
        return flag;
    }

    /**
     * 修改用户选择
     */
    @Override
    public Boolean updateByBo(TSelectUserBo bo) {
        TSelectUser update = BeanUtil.toBean(bo, TSelectUser.class);
        // validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TSelectUser entity) {
        //TODO 做一些数据校验,如唯一约束
        //判断是否可选
        switch (canSubsidy(entity.getUserId(), entity.getTimeId())) {
            case 1:
                throw new IllegalArgumentException("入职未满两年");
            case 2:
                throw new IllegalArgumentException("已在本轮活动中申请过省外或国外路线");
            case 3:
                break;
        }
        switch (canSelect(entity.getUserId(), entity.getTimeId())) {
            case 1:
                throw new IllegalArgumentException("该时间段未开启补报");
            case 2:
                throw new IllegalArgumentException("不在在可选时间内");
            case 3:
                throw new IllegalArgumentException("该路线不是本单位开设的路线");
            case 4:
                throw new IllegalArgumentException("余量不足");
            case 5:
                throw new IllegalArgumentException("未到补报时间，请选择本部门开设的专属路线");
            case 6:
                break;

        }
        if (isSelect(entity.getUserId(), entity.getTimeId())) {
            throw new IllegalArgumentException("已经选过该路线");
        }

        if (canJoin(entity.getUserId())) {
            throw new IllegalArgumentException("本年度报名次数已到上限");
        }


    }

    /**
     * 批量删除用户选择
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 重置教职工项目轮数
     */
    @Override
    public Boolean resetSelectUser() {
        // 将 t_select_user 表中的 round 字段重置为 1
        LambdaQueryWrapper<TSelectUser> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(TSelectUser::getRound, false);
        List<TSelectUser> selectUsers = baseMapper.selectList(queryWrapper);
        selectUsers.forEach(selectUser -> selectUser.setRound(1));
        if (selectUsers.isEmpty()) {
            return true;
        }
        return baseMapper.updateBatchById(selectUsers);
    }


    @Override
    public int canSelect(Long userId, Long timeId) {
        Date now = new Date();
        TTime tTime = timeMapper.selectById(timeId);
        TRoute tRoute = routeMapper.selectById(tTime.getRouteId());
        TProject tProject = projectMapper.selectById(tRoute.getProjectId());
        //判断是否在可选时间内
        if (tProject.getStartTime().after(now) || tProject.getEndTime().before(now)) {
            if (tProject.getReselectStart() != null && tProject.getReselectEnd() != null) {
                if (tTime.getStatus() == 0|| tProject.getReselectStart().after(now) || tProject.getReselectEnd().before(now)) {
                    return 2;
                }
            }
        }
        //判断路线是否是本单位开设的路线(可以多选)

        if(tRoute.getAllowUnifiedCode()!=1){
            {
                TUser tUser = userMapper.selectById(userId);
                TStaff tStaff=itStaffService.selectByZgh(tUser.getZgh());
                //DepartmentNo字段为数组，判断当前职工所属部门是否在数组中
                String[] departmentNo=tRoute.getDepartmentNo().split(",");
                for(String department:departmentNo){
                    if(department.equals(tStaff.getDWDM())){
                        return 3;
                    }
                }
            }
        }
        if (tProject.getStartTime().before(now) && tProject.getEndTime().after(now) && tRoute.getAllowUnifiedCode()==1) {
            //若当前职工有专属路线则不可报名其他路线
            TUser tUser = userMapper.selectById(userId);
            TStaff tStaff = itStaffService.selectByZgh(tUser.getZgh());
            //获取所有有专属路线路线的部门编号
            LambdaQueryWrapper<TRoute> lqw1 = Wrappers.lambdaQuery();
            lqw1.eq(TRoute::getAllowUnifiedCode, 0);
            //获取可报名路线
            lqw1.eq(TRoute::getProjectId, tProject.getId());
            //当前路线状态为可选
            lqw1.eq(TRoute::getStatusCode, 3);
            List<TRoute> tRoutes = routeMapper.selectList(lqw1);

            for (int i = 0; i < tRoutes.size(); i++) {
                String[] departmentNo = tRoute.getDepartmentNo().split(",");
                for (String department : departmentNo) {
                    if (department.equals(tStaff.getDWDM())) {
                        return 5;
                    }
                }
            }
        }

        //判断余量是否充足（家属报满后可以继续报名职工）
        if (tTime.getStaffCount() >= tTime.getStaffMax()) {
            return 4;
        }
        return 6;
    }

    @Override
    public Boolean isSelect(Long userId, Long timeId) {
        LambdaQueryWrapper<TSelectUser> lqw = Wrappers.lambdaQuery();
        lqw.eq(TSelectUser::getUserId, userId);
        lqw.eq(TSelectUser::getTimeId, timeId);
        lqw.eq(TSelectUser::getRound,0);
        return baseMapper.selectCount(lqw) > 0;
    }

    @Override
    public int canSubsidy(Long userId, Long timeId) {
        TTime tTime = timeMapper.selectById(timeId);
        TRoute tRoute = routeMapper.selectById(tTime.getRouteId());
        TPolicy policy = policyMapper.selectById(1);
        LambdaQueryWrapper<TSelectUser> lqw = Wrappers.lambdaQuery();
        lqw.eq(TSelectUser::getUserId, userId);
        lqw.eq(TSelectUser::getRound,0);
        //获取当前年份
        int year = new Date().getYear() + 1900;

        /**添加入职时间参数限制：是否限制入职时间，如果限制限制年限多少年*/
        TUser tUser = userMapper.selectById(userId);
        TStaff tStaff = itStaffService.selectByZgh(tUser.getZgh());
        if (tStaff.getRZSJ() != null) {
            if (policy.getRzsjLimit() != 0) {
                //获取入职时间限制年份
                int rzsjLimit = policy.getRzsjLimit();
                //获取两年前的7月1号
                Date date = new Date();
                date.setYear(date.getYear() - rzsjLimit);
                date.setMonth(6);
                date.setDate(1);
                if (tStaff.getRZSJ().after(date)) {
                    return 1;
                }
            }

        }


        if ( tRoute.getAreaCode()==1) {
            //从项目中提取项目起止年份，以此为依据查询省内外省外国限制

            lqw.eq(TSelectUser::getArea, 1);
            //根据政策执行年份，判断报名时间限制
            if(policy.getNewCalculateYear()!=null)
                //比较当前年份减去限制年份后是否大于政策执行年份

                if(year-policy.getOutProvinceYear()> policy.getNewCalculateYear().getValue()){
                    //如果大于则将政策执行年份赋值给year
                    lqw.between(TSelectUser::getYear, year - policy.getOutProvinceYear(), year);}
                else {
                    lqw.between(TSelectUser::getYear,  policy.getNewCalculateYear().getValue(), year);
                }

           if( baseMapper.selectCount(lqw) >= policy.getOutProvinceNum() )
               return  2   ;
        }
        else if(tRoute.getAreaCode()==2) {


            lqw.eq(TSelectUser::getArea, 2);
            //比较当前年份减去限制年份后是否大于政策执行年份
            if (year - policy.getAbroadYear() > policy.getNewCalculateYear().getValue()) {
                //如果大于则将政策执行年份赋值给year
                lqw.between(TSelectUser::getYear, year - policy.getAbroadYear(), year);
            } else {
                lqw.between(TSelectUser::getYear, policy.getNewCalculateYear().getValue(), year);
            }
            if(baseMapper.selectCount(lqw) >= policy.getAbroadNum())
               return 2;
        }
        return 3;
    }

    @Override
    //判断用户今年报名次数是否已经达到上限
    public boolean canJoin(long userId) {
        TPolicy policy = policyMapper.selectById(1);
        LambdaQueryWrapper<TSelectUser> lqw = Wrappers.lambdaQuery();
        lqw.eq(TSelectUser::getRound,0);
        lqw.eq(TSelectUser::getUserId, userId);
        lqw.between(TSelectUser::getYear, new Date().getYear() + 1900 - policy.getJoinYear(), new Date().getYear() + 1900);
        return baseMapper.selectCount(lqw) >= policy.getJoinNum();
    }

    //用户退选
    public boolean deleteWithValidById(Long userId, Long timeId, Boolean isValid) {
        LambdaQueryWrapper<TSelectUser> lqw = Wrappers.lambdaQuery();
        lqw.eq(TSelectUser::getUserId, userId);
        lqw.eq(TSelectUser::getTimeId, timeId);
        LambdaQueryWrapper<TDependant> lqw1 = Wrappers.lambdaQuery();
        lqw1.eq(TDependant::getUserId, userId);
        Collection<Long> ids = dependantMapper.selectVoList(lqw1).stream().map(TDependantVo::getId).collect(java.util.stream.Collectors.toList());
        if (!ids.isEmpty()) {
            tDependantService.deleteWithValidById(ids, timeId, true);
            ;
        }

        TTime tTime = timeMapper.selectById(timeId);
        tTime.setCount(tTime.getCount() - 1);
        tTime.setStaffCount(tTime.getStaffCount() - 1);
        timeMapper.updateById(tTime);
        return baseMapper.delete(lqw) > 0;
    }


}
